﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using CsGL.OpenGL;
using System.Runtime.InteropServices;

namespace testyOpenCV
{

	public class OurView : OpenGLControl
	{
		public float AAA = 1.5f;
		public bool disableDrawing = true;
		public float[] translateScene = new float[3];
		public float[] rotateScene = new float[3];
		private Form1 handle;
		public class MouseMoveController : Object
		{
			public static float x0 = 0;
			public static float y0 = 0;
			public static int posX0 = 0;
			public static int posY0 = 0;
			public static float yrot0 = 0;
			public static float xrot0 = 0;
			public static bool pressedLeft = false;
			public static bool pressedRight = false;
		};
		[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
		private static extern short GetKeyState(int keyCode);
		MouseMoveController mmc = new MouseMoveController();
		public OurView(Form1 f)
			: base()
		{
			handle = f;
			disableDrawing = false;
			translateScene[0] = 1.5f;
			translateScene[1] = 0.0f;
			translateScene[2] = -6.0f;
			rotateScene[0] = 0.0f;
			rotateScene[1] = 0.0f;
			rotateScene[2] = 0.0f;

			this.KeyDown += new KeyEventHandler(OurView_OnKeyDown);
			
		}
		public override void glDraw()
		{
			if (disableDrawing == true)
				return;

			GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer     
			GL.glLoadIdentity();                 // Reset The Current Modelview Matrix         
			
			if (handle.img == null)
				return;
			
			float[] LightAmbient = new float[4];                // Ambient Light Values ( NEW )
			LightAmbient[0] = 0.5f;
			LightAmbient[1] = 0.5f;
			LightAmbient[2] = 0.5f;
			LightAmbient[3] = 1.0f;

			float[] LightDiffuse = new float[4];                // Ambient Light Values ( NEW )
			LightAmbient[0] = 0.5f;
			LightAmbient[1] = 0.5f;
			LightAmbient[2] = 0.5f;
			LightAmbient[3] = 1.0f;

			float[] LightPosition = new float[4];
			LightPosition[0] = 0.0f;
			LightPosition[1] = 0.0f;
			LightPosition[2] = 2.0f;
			LightPosition[3] = 1.0f;

			GL.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, LightAmbient);		// Setup The Ambient Light
			GL.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, LightDiffuse);		// Setup The Ambient Light
			GL.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, LightPosition);	// Position The Light

			GL.glEnable(GL.GL_LIGHTING);
			
			GL.glTranslatef(translateScene[0], translateScene[1], translateScene[2]);
			GL.glRotatef(rotateScene[0], 1.0f, 0.0f, 0.0f); // Rotate On The X Axis
			GL.glRotatef(rotateScene[1], 0.0f, 1.0f, 0.0f); // Rotate On The Y Axis
			GL.glRotatef(rotateScene[2], 0.0f, 0.0f, 1.0f); // Rotate On The Z Axis 

			// obrazek - rysuj sie !
			handle.img.drawMyselfOGL();

			/* commented by KPC
			DrawCube(0f, 0f, 0f, 0.1f);
			DrawCube(1f, 1f, 0, 0.6f);
			 */
			
			
			//for (int i = 0; i < handle.img.cubs.Length; i++)
			//handle.img.cubs[i].draw();
			//handle.img

			/*
			GL.glBegin(GL.GL_QUADS); // Begin Drawing Triangles
						
			 GL.glColor3f(0.0f, 1.0f, 0.0f);          // Set The Color To Green 
			 GL.glVertex3f(1.0f, 1.0f, -1.0f);          // Top Right Of The Quad (Top) 
			 GL.glVertex3f(-1.0f, 1.0f, -1.0f);          // Top Left Of The Quad (Top) 
			 GL.glVertex3f(-1.0f, 1.0f, 1.0f);          // Bottom Left Of The Quad (Top) 
			 GL.glVertex3f(1.0f, 1.0f, 1.0f);          // Bottom Right Of The Quad (Top)

			 GL.glColor3f(1.0f, 0.5f, 0.0f);          // Set The Color To Orange 
			 GL.glVertex3f(1.0f, -1.0f, 1.0f);          // Top Right Of The Quad (Bottom) 
			 GL.glVertex3f(-1.0f, -1.0f, 1.0f);          // Top Left Of The Quad (Bottom) 
			 GL.glVertex3f(-1.0f, -1.0f, -1.0f);          // Bottom Left Of The Quad (Bottom) 
			 GL.glVertex3f(1.0f, -1.0f, -1.0f);          // Bottom Right Of The Quad (Bottom)

			 GL.glColor3f(1.0f, 0.0f, 0.0f);          // Set The Color To Red 
			 GL.glVertex3f(1.0f, 1.0f, 1.0f);          // Top Right Of The Quad (Front) 
			 GL.glVertex3f(-1.0f, 1.0f, 1.0f);          // Top Left Of The Quad (Front) 
			 GL.glVertex3f(-1.0f, -1.0f, 1.0f);          // Bottom Left Of The Quad (Front) 
			 GL.glVertex3f(1.0f, -1.0f, 1.0f);          // Bottom Right Of The Quad (Front)

			 GL.glColor3f(1.0f, 1.0f, 0.0f);          // Set The Color To Yellow 
			 GL.glVertex3f(1.0f, -1.0f, -1.0f);          // Bottom Left Of The Quad (Back) 
			 GL.glVertex3f(-1.0f, -1.0f, -1.0f);          // Bottom Right Of The Quad (Back) 
			 GL.glVertex3f(-1.0f, 1.0f, -1.0f);          // Top Right Of The Quad (Back) 
			 GL.glVertex3f(1.0f, 1.0f, -1.0f);          // Top Left Of The Quad (Back)

			 GL.glColor3f(0.0f, 0.0f, 1.0f);          // Set The Color To Blue 
			 GL.glVertex3f(-1.0f, 1.0f, 1.0f);          // Top Right Of The Quad (Left) 
			 GL.glVertex3f(-1.0f, 1.0f, -1.0f);          // Top Left Of The Quad (Left) 
			 GL.glVertex3f(-1.0f, -1.0f, -1.0f);          // Bottom Left Of The Quad (Left) 
			 GL.glVertex3f(-1.0f, -1.0f, 1.0f);          // Bottom Right Of The Quad (Left)

			 GL.glColor3f(1.0f, 0.0f, 1.0f);          // Set The Color To Violet 
			 GL.glVertex3f(1.0f, 1.0f, -1.0f);          // Top Right Of The Quad (Right) 
			 GL.glVertex3f(1.0f, 1.0f, 1.0f);          // Top Left Of The Quad (Right) 
			 GL.glVertex3f(1.0f, -1.0f, 1.0f);          // Bottom Left Of The Quad (Right) 
			 GL.glVertex3f(1.0f, -1.0f, -1.0f);          // Bottom Right Of The Quad (Right)
			*/
			/*
			GL.glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
			GL.glVertex3f(0.0f, 1.0f, 0.0f); // Move Up One Unit From Center (Top Point)

			GL.glColor3f(0.0f, 1.0f, 0.0f); // Set The Color To Green
			GL.glVertex3f(-1.0f, -1.0f, 0.0f); // Left And Down One Unit (Bottom Left)

			GL.glColor3f(0.0f, 0.0f, 1.0f); // Set The Color To Blue
			GL.glVertex3f(1.0f, -1.0f, 0.0f); // Right And Down One Unit (Bottom Right)
			 */
			//GL.glEnd(); 

		}
		protected override void InitGLContext()
		{
			GL.glShadeModel(GL.GL_SMOOTH);         // Set Smooth Shading                 
			GL.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);     // BackGround Color         
			GL.glClearDepth(1.0f);                 // Depth buffer setup             
			GL.glEnable(GL.GL_DEPTH_TEST);         // Enables Depth Testing             
			GL.glDepthFunc(GL.GL_LEQUAL);             // The Type Of Depth Test To Do     
			GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);     /* Really Nice Perspective Calculations */
		}
		protected override void OnSizeChanged(EventArgs e)
		{
			base.OnSizeChanged(e);

			Size s = Size;
			double aspect_ratio = (double)s.Width / (double)s.Height;
			GL.glMatrixMode(GL.GL_PROJECTION); // Select The Projection Matrix
			GL.glLoadIdentity(); // Reset The Projection Matrix

			// Calculate The Aspect Ratio Of The Window
			GL.gluPerspective(45.0f, aspect_ratio, 0.1f, 100.0f);

			GL.glMatrixMode(GL.GL_MODELVIEW); // Select The Modelview Matrix
			GL.glLoadIdentity();// Reset The Modelview Matrix
		}
		protected void OurView_OnKeyDown(object Sender, KeyEventArgs kea)
		{
			if (kea.KeyCode == Keys.Q && kea.Modifiers == Keys.Shift)
			{
				Application.Exit();
			}
		}
		protected override void OnMouseWheel(MouseEventArgs e)
		{
			base.OnMouseWheel(e);
			int val = e.Delta;
			if (val < 0)
				val = -val;

			translateScene[2] += (e.Delta) * 0.5f / (val);
		}
		protected override void OnMouseClick(MouseEventArgs e)
		{
			base.OnMouseClick(e);
			handle.setOpenGlWindowFocus();
		}
		
		public void DrawCube(float X, float Y, float Z, float size)
		{
			GL.glPushMatrix();

			GL.glTranslatef(X, Y, Z);

			GL.glPushMatrix();
			scianaXY(size);
			GL.glPopMatrix();

			GL.glPushMatrix();
			scianaXZ(size);
			GL.glPopMatrix();

			GL.glPushMatrix();
			scianaYZ(size);
			GL.glPopMatrix();

			GL.glPopMatrix();
		}
		public void scianaXY(float size)
		{
			GL.glBegin(GL.GL_QUADS); // Begin Drawing Triangles
			GL.glColor3f(0.0f, 1.0f, 0.0f);
			GL.glVertex3f(0.0f, 0.0f, 0.0f);
			GL.glVertex3f(size, 0.0f, 0.0f);
			GL.glVertex3f(size, size, 0.0f);
			GL.glVertex3f(0.0f, size, 0.0f);
			GL.glEnd();

			GL.glTranslatef(0.0f, 0.0f, size);
			GL.glBegin(GL.GL_QUADS); // Begin Drawing Triangles
			GL.glColor3f(0.0f, 1.0f, 0.0f);
			GL.glVertex3f(0.0f, 0.0f, 0.0f);
			GL.glVertex3f(size, 0.0f, 0.0f);
			GL.glVertex3f(size, size, 0.0f);
			GL.glVertex3f(0.0f, size, 0.0f);
			GL.glEnd();
		}

		public void scianaXZ(float size)
		{
			GL.glBegin(GL.GL_QUADS); // Begin Drawing Triangles
			GL.glColor3f(0.0f, 1.0f, 0.0f);
			GL.glVertex3f(0.0f, 0.0f, 0.0f);
			GL.glVertex3f(size, 0.0f, 0.0f);
			GL.glVertex3f(size, 0.0f, size);
			GL.glVertex3f(0.0f, 0.0f, size);
			GL.glEnd();

			GL.glTranslatef(0.0f, size, 0.0f);
			GL.glBegin(GL.GL_QUADS); // Begin Drawing Triangles
			GL.glColor3f(0.0f, 1.0f, 0.0f);
			GL.glVertex3f(0.0f, 0.0f, 0.0f);
			GL.glVertex3f(size, 0.0f, 0.0f);
			GL.glVertex3f(size, 0.0f, size);
			GL.glVertex3f(0.0f, 0.0f, size);
			GL.glEnd();
		}

		public void scianaYZ(float size)
		{
			GL.glBegin(GL.GL_QUADS); // Begin Drawing Triangles
			GL.glColor3f(0.0f, 1.0f, 0.0f);
			GL.glVertex3f(0.0f, 0.0f, 0.0f);
			GL.glVertex3f(0.0f, size, 0.0f);
			GL.glVertex3f(0.0f, size, size);
			GL.glVertex3f(0.0f, 0.0f, size);
			GL.glEnd();

			GL.glBegin(GL.GL_QUADS); // Begin Drawing Triangles
			GL.glColor3f(0.0f, 1.0f, 0.0f);
			GL.glVertex3f(0.0f, 0.0f, 0.0f);
			GL.glVertex3f(0.0f, size, 0.0f);
			GL.glVertex3f(0.0f, size, size);
			GL.glVertex3f(0.0f, 0.0f, size);
			GL.glEnd();
		}
		protected override void OnMouseMove(MouseEventArgs e)
		{
			base.OnMouseMove(e);

			// Sprawdza czy wcisnięto lewy przycisk myszy.
			if ((GetKeyState((int)Keys.LButton) & 0x80) != 0)
			{

				if (!MouseMoveController.pressedLeft)
				{
					MouseMoveController.posX0 = e.X;
					MouseMoveController.posY0 = e.Y;
					MouseMoveController.pressedLeft = true;
				}
				translateScene[0] = MouseMoveController.x0 - (float)(e.X - MouseMoveController.posX0) * translateScene[2] / 200;
				translateScene[1] = MouseMoveController.y0 + (float)(e.Y - MouseMoveController.posY0) * translateScene[2] / 200;

			}
			else
			{
				MouseMoveController.x0 = translateScene[0];
				MouseMoveController.y0 = translateScene[1];
				MouseMoveController.pressedLeft = false;
			}

			// Sprawdza czy wciśnięto prawy przycisk myszy.
			if ((GetKeyState((int)Keys.RButton) & 0x80) != 0)
			{
				if (!MouseMoveController.pressedRight)
				{
					MouseMoveController.posX0 = e.X;
					MouseMoveController.posY0 = e.Y;
					MouseMoveController.pressedRight = true;
				}
				rotateScene[1] = MouseMoveController.yrot0 + (float)(e.X - MouseMoveController.posX0) / 2.0f;
				rotateScene[0] = MouseMoveController.xrot0 + (float)(e.Y - MouseMoveController.posY0) / 2.0f;
			}
			else
			{
				MouseMoveController.yrot0 = rotateScene[1];
				MouseMoveController.xrot0 = rotateScene[0];
				MouseMoveController.pressedRight = false;
			}
		}
	}
}
